#include <sys/types.h>
/*
 * sbuffer.h
 *
 *  Created on: Sep 9, 2010
 *      Author: thienlong
 */

#ifndef SBUFFER_H_
#define SBUFFER_H_
#define STRING_BUFFER_PIECE_SIZE 64
#define STRING_BUFFER_MAX_REUSE_SIZE 4096
typedef struct {
	struct next_object *next;
	char *ptr;

	size_t used;
	size_t size;
} stringbuffer;

typedef struct {
	struct next_object *next;
	stringbuffer **ptr;

	size_t used;
	size_t size;
} stringbuffer_array;

stringbuffer_array* stringbuffer_array_new(void);
void stringbuffer_array_free(stringbuffer_array *b);
void stringbuffer_array_reset(stringbuffer_array *b);
stringbuffer *stringbuffer_array_append_get_stringbuffer(stringbuffer_array *b);

stringbuffer* stringbuffer_new(void);
stringbuffer* stringbuffer_new_stringbuffer(stringbuffer *b);
stringbuffer* stringbuffer_new_string(const char *str);
void stringbuffer_free(stringbuffer *b);
void stringbuffer_reset(stringbuffer *b);
int stringbuffer_prepare_copy(stringbuffer *b, size_t size);
int stringbuffer_prepare_append(stringbuffer *b, size_t size);

int stringbuffer_copy_string(stringbuffer *b, const char *s);
int stringbuffer_copy_string_len(stringbuffer *b, const char *s, size_t s_len);
int stringbuffer_copy_stringbuffer(stringbuffer *b, const stringbuffer *src);
int stringbuffer_copy_string_hex(stringbuffer *b, const char *in, size_t in_len);

int stringbuffer_copy_long(stringbuffer *b, long val);

int stringbuffer_copy_memory(stringbuffer *b, const char *s, size_t s_len);

int stringbuffer_append_string(stringbuffer *b, const char *s);
int stringbuffer_append_char(stringbuffer *b, char c);
int stringbuffer_append_string_len(stringbuffer *b, const char *s, size_t s_len);
int stringbuffer_append_stringbuffer(stringbuffer *b, const stringbuffer *src);
int stringbuffer_append_string_lfill(stringbuffer *b, const char *s, size_t maxlen);
int stringbuffer_append_string_rfill(stringbuffer *b, const char *s, size_t maxlen);
int stringbuffer_append_long_hex(stringbuffer *b, unsigned long len);
int stringbuffer_append_long(stringbuffer *b, long val);

#if defined(SIZEOF_LONG) && (SIZEOF_LONG == SIZEOF_OFF_T)
#define buffer_copy_off_t(x, y)		buffer_copy_long(x, y)
#define buffer_append_off_t(x, y)	buffer_append_long(x, y)
#else
int stringbuffer_copy_off_t(stringbuffer *b, off_t val);
int stringbuffer_append_off_t(stringbuffer *b, off_t val);
#endif

int stringbuffer_append_memory(stringbuffer *b, const char *s, size_t len);
int stringbuffer_overwrite_string(stringbuffer *b, off_t offset, const char *s, size_t len);
int stringbuffer_overwrite_long(stringbuffer *b, off_t offset, long val);
int stringbuffer_overwrite_ulong(stringbuffer *b, off_t offset, unsigned long val);
char * stringbuffer_search_string_len(stringbuffer *b, const char *needle, size_t len);

int stringbuffer_is_empty(stringbuffer *b);
int stringbuffer_is_equal(stringbuffer *a, stringbuffer *b);
int stringbuffer_is_equal_right_len(stringbuffer *a, stringbuffer *b, size_t len);
int stringbuffer_is_equal_string(stringbuffer *a, const char *s, size_t b_len);
int stringbuffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len);

typedef enum {
	ENCODING_UNSET,
	ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
	ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
	ENCODING_HTML,         /* & becomes &amp; and so on */
	ENCODING_MINIMAL_XML,  /* minimal encoding for xml */
	ENCODING_HEX,          /* encode string as hex */
	ENCODING_HTTP_HEADER   /* encode \n with \t\n */
} encoding_t;

int stringbuffer_append_string_encoded(stringbuffer *b, const char *s, size_t s_len, encoding_t encoding);
int stringbuffer_append_string_decoded(stringbuffer *b, const char*s, size_t s_len);
int stringbuffer_copy_string_decoded(stringbuffer *buf, const char*s, size_t s_len);
int stringbuffer_urldecode_path(stringbuffer *url);
int stringbuffer_urldecode_query(stringbuffer *url);
int stringbuffer_path_simplify(stringbuffer *dest, stringbuffer *src);

int stringbuffer_to_lower(stringbuffer *b);
int stringbuffer_to_upper(stringbuffer *b);

int ulong_to_char_array(char *buf, unsigned long val);
int long_to_char_array(char *buf, long val);
int ulong_to_string(char *buf, unsigned long val);
int long_to_string(char *buf, long val);
#endif /* SBUFFER_H_ */
